home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / extras / Direct3D / Tools / Maya25 / MyDt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  14.1 KB  |  755 lines

  1.  
  2. #include "MyDt.h"
  3. #include "MyAssert.h"
  4.  
  5. // Maya API
  6. #include <maya/MObject.h>
  7. #include <maya/MColor.h>
  8. #include <maya/MMatrix.h>
  9. #include <maya/MDagPath.h>
  10. #include <maya/MTime.h>
  11. #include <maya/MAnimControl.h>
  12. #include <maya/MFileObject.h>
  13. #include <maya/MPlug.h>
  14.  
  15.  
  16. #include <maya/MIntArray.h>
  17. #include <maya/MFloatArray.h>
  18. #include <maya/MFloatVectorArray.h>
  19. #include <maya/MFloatPointArray.h>
  20. #include <maya/MPointArray.h>
  21. #include <maya/MObjectArray.h>
  22. #include <maya/MDagPathArray.h>
  23. #include <maya/MPlugArray.h>
  24. #include <maya/MSelectionList.h>
  25.  
  26. #include <maya/MFnMatrixData.h>
  27. #include <maya/MFnMeshData.h>
  28. #include <maya/MFnDoubleArrayData.h>
  29. #include <maya/MFnVectorArrayData.h>
  30.  
  31. #include <maya/MFnSingleIndexedComponent.h>
  32. #include <maya/MFnSet.h>
  33. #include <maya/MFnTypedAttribute.h>
  34. #include <maya/MFnSkinCluster.h>
  35. #include <maya/MFnWeightGeometryFilter.h>
  36. #include <maya/MFnDagNode.h>
  37. #include <maya/MFnIKJoint.h>
  38. #include <maya/MFnMesh.h>
  39. #include <maya/MFnNurbsSurface.h>
  40. #include <maya/MFnLambertShader.h>
  41.  
  42. #include <maya/MItDependencyNodes.h>
  43. #include <maya/MItGeometry.h>
  44.  
  45.  
  46. bool    g_bRelativeTexFile;
  47. bool    g_bExportAnimation;
  48. bool    g_bKeyframeAnimation;
  49. bool    g_bAnimateEverything;
  50. int        g_iFrameStep;
  51. int        g_iFlipU;
  52. int        g_iFlipV;
  53. bool    g_bExportPatches;
  54.  
  55. StringTable    g_Strings;
  56.  
  57.  
  58.  
  59. int    MyDtShapeGetParentID
  60.     (
  61.         int    iShape
  62.     ) 
  63. {
  64.     int    cShapes        = DtShapeGetCount();
  65.  
  66.  
  67.     MObject    objTransform;
  68.  
  69.     DtExt_ShapeGetTransform(iShape, objTransform);
  70.  
  71.     MFnDagNode    fnNode(objTransform);
  72.  
  73.     int cParents    = fnNode.parentCount();
  74.  
  75.     for (int iParent = 0; iParent < cParents; iParent++) 
  76.     {
  77.         MFnDagNode    fnParent(fnNode.parent(iParent));
  78.  
  79.         for (int iShape_ = 0; iShape_ < cShapes; iShape_++) 
  80.         {
  81.             MObject    objTransform_;
  82.  
  83.             DtExt_ShapeGetTransform(iShape_, objTransform_);
  84.  
  85.             if (fnParent.fullPathName() == MFnDagNode(objTransform_).fullPathName())
  86.                 return iShape_;
  87.         }
  88.     }
  89.  
  90.     return -1;
  91. }
  92.  
  93.  
  94.  
  95. int MyDtShapeGetChildren
  96.     (
  97.         int     iShape, 
  98.         int*    cChildren, 
  99.         int**   rgiChildren
  100.     ) 
  101. {
  102.     int    cShapes        = DtShapeGetCount();
  103.  
  104.     MObject    objTransform;
  105.  
  106.     DtExt_ShapeGetTransform(iShape, objTransform);
  107.  
  108.     MFnDagNode    fnNode(objTransform);
  109.  
  110.     int cChildren_    = fnNode.childCount();
  111.  
  112.     *cChildren        = 0;
  113.  
  114.     if (cChildren_ > 0) 
  115.     {
  116.         *rgiChildren    = new int[cChildren_];
  117.  
  118.     
  119.         for (int iChild = 0; iChild < cChildren_; iChild++) 
  120.         {
  121.             MFnDagNode fnChild(fnNode.child(iChild));
  122.  
  123.             for (int iShape_ = 0; iShape_ < cShapes; iShape_++) 
  124.             {
  125.                 MObject    objTransform_;
  126.  
  127.                 DtExt_ShapeGetTransform(iShape_, objTransform_);
  128.  
  129.                 if (fnChild.fullPathName() == MFnDagNode(objTransform_).fullPathName()) 
  130.                 {
  131.                     (*rgiChildren)[*cChildren]    = iShape_;
  132.                     (*cChildren)++;
  133.  
  134.                     break;
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     else
  140.         *rgiChildren    = new int[1];    // just in case delete doesn't like "int[0]"
  141.  
  142.     return 1;
  143. }
  144.  
  145.  
  146. int    MyDtShapeGetVertices
  147.     (
  148.         MObject&    objInput, 
  149.         MObject&    objOutput, 
  150.         int*        pcVertices, 
  151.         DtVec3f**    prgVertices
  152.     ) 
  153. {
  154.     *pcVertices        = 0;
  155.     *prgVertices    = NULL;
  156.  
  157.     
  158.     assert(objInput.hasFn(MFn::kMesh) && objOutput.hasFn(MFn::kMesh));
  159.  
  160.  
  161.     MFnMesh    fnOutput(objOutput);
  162.     MFnMesh    fnInput(objInput);
  163.  
  164.     *pcVertices        = fnOutput.numVertices();
  165.     *prgVertices    = new DtVec3f[*pcVertices];
  166.  
  167.     if (!*prgVertices) 
  168.     {
  169.         *pcVertices    = 0;
  170.  
  171.         return 0;
  172.     }
  173.  
  174.     // check for tweaks
  175.     MPlug    plgTweakLoc    = fnOutput.findPlug("tweakLocation");
  176.  
  177.     MObject    objTweakLocVal;
  178.  
  179.     plgTweakLoc.getValue(objTweakLocVal);
  180.  
  181.     if (!objTweakLocVal.isNull())    // tweak found
  182.     {    
  183.         MPlugArray    rgplgTweakLocConnections;
  184.  
  185.         plgTweakLoc.connectedTo(rgplgTweakLocConnections, true, false);        // get source plugs
  186.  
  187.         assert(rgplgTweakLocConnections.length() == 1);
  188.  
  189.         MObject    objTweak = rgplgTweakLocConnections[0].node();
  190.  
  191.         assert(objTweak.hasFn(MFn::kTweak));
  192.  
  193.         MFnGeometryFilter    fnTweak(objTweak);
  194.  
  195.         bool    bRelativeTweak;
  196.  
  197.         fnTweak.findPlug("relativeTweak").getValue(bRelativeTweak);
  198.  
  199.         if (!bRelativeTweak) 
  200.             cout << "\t\tWARNING: Encountered an absolute tweak; treating as relative!" << endl;
  201.  
  202.         MPlug plgOffsets = fnTweak.findPlug("vlist")[0].child(0);
  203.  
  204.  
  205.         //    WARNING: Seems like Maya doesn't initialize it's numElements properly!!
  206. //        assert((int)plgOffsets.numElements() == cVertices);
  207. //        if ((int)plgOffsets.numElements() != *pcVertices)
  208. //            cout << "\t\tWARNING: tweak count doesn't match vertex count!" << endl;
  209.  
  210.         float    fEnvelope    = fnTweak.envelope();
  211.  
  212.         for (int iVertex = 0; iVertex < *pcVertices; iVertex++) 
  213.         {
  214.             plgOffsets.elementByLogicalIndex(iVertex).child(0).getValue((*prgVertices)[iVertex].vec[0]);
  215.             plgOffsets.elementByLogicalIndex(iVertex).child(1).getValue((*prgVertices)[iVertex].vec[1]);
  216.             plgOffsets.elementByLogicalIndex(iVertex).child(2).getValue((*prgVertices)[iVertex].vec[2]);
  217.  
  218.             (*prgVertices)[iVertex].vec[0]    *= fEnvelope;
  219.             (*prgVertices)[iVertex].vec[1]    *= fEnvelope;
  220.             (*prgVertices)[iVertex].vec[2]    *= fEnvelope;
  221.         }
  222.     }
  223.     else 
  224.     {
  225.         for (int iVertex = 0; iVertex < *pcVertices; iVertex++) 
  226.         {
  227.             (*prgVertices)[iVertex].vec[0]    = 0.0f;
  228.             (*prgVertices)[iVertex].vec[1]    = 0.0f;
  229.             (*prgVertices)[iVertex].vec[2]    = 0.0f;
  230.         }
  231.     }
  232.             
  233.             
  234.  
  235.     // load vertices and add them to the tweaks
  236.     assert(*pcVertices == fnInput.numVertices());
  237.  
  238.     MFloatPointArray rgOrigVertices;
  239.  
  240.     fnInput.getPoints(rgOrigVertices);
  241.  
  242.     assert(*pcVertices == (int)rgOrigVertices.length());
  243.  
  244.     for (int iVertex = 0; iVertex < *pcVertices; iVertex++) 
  245.     {
  246.         (*prgVertices)[iVertex].vec[0] += rgOrigVertices[iVertex][0];
  247.         (*prgVertices)[iVertex].vec[1] += rgOrigVertices[iVertex][1];
  248.         (*prgVertices)[iVertex].vec[2] += rgOrigVertices[iVertex][2];
  249.     }
  250.  
  251.  
  252.     return 1;
  253. }
  254.  
  255.  
  256. int    MyDtTextureGetFileName
  257.     (
  258.         char*    szMaterial, 
  259.         char**    pszTextureFile
  260.     )
  261. {
  262.     if (!DtTextureGetFileName(szMaterial, pszTextureFile))
  263.         return 0;
  264.  
  265.     if (g_bRelativeTexFile && *pszTextureFile) 
  266.     {
  267.         // use a trick to get the file name without too much hassle
  268.         MFileObject mFile;
  269.  
  270.         mFile.setFullName(MString(*pszTextureFile));
  271.  
  272.         *pszTextureFile = new char[256];
  273.  
  274.         if (*pszTextureFile == NULL)
  275.             return 0;
  276.  
  277.         strcpy(*pszTextureFile, mFile.name().asChar());
  278.  
  279.         g_Strings.add(*pszTextureFile);
  280.     }
  281.  
  282.     return 1;
  283. }
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291. bool    MyDtShapeIsJoint
  292.         (
  293.             int    iShape
  294.         ) 
  295. {
  296.     MObject    objShape;
  297.  
  298.     DtExt_ShapeGetShapeNode(iShape, objShape);
  299.  
  300.     return (objShape.apiType() == MFn::kInvalid);
  301. }
  302.  
  303.  
  304.  
  305.  
  306.  
  307. bool    MyDtShapeIsPatchMesh
  308.         (
  309.             int    iShape
  310.         ) 
  311. {
  312.     MObject    objNurb;
  313.  
  314.     DtExt_ShapeGetShapeNode(iShape, objNurb);
  315.  
  316.     if (!objNurb.hasFn(MFn::kNurbsSurface))
  317.         return    false;        // not a nurbs surface
  318.  
  319.     MFnNurbsSurface    fnNurb(objNurb);
  320.  
  321.     if (fnNurb.degreeU() != 3 || fnNurb.degreeV() != 3)    
  322.         return false;        // not a bicubic surface
  323.  
  324.     int    kFormInU    = fnNurb.formInU();
  325.     int    kFormInV    = fnNurb.formInV();
  326.  
  327.     if (kFormInU == MFnNurbsSurface::kInvalid || kFormInV == MFnNurbsSurface::kInvalid)
  328.         return false;        // surface has invalid form
  329.  
  330.     if (kFormInU == MFnNurbsSurface::kPeriodic || kFormInV == MFnNurbsSurface::kPeriodic)
  331.         return false;        // can't handle periodic surfaces
  332.     
  333.     int    cCVsInU    = fnNurb.numCVsInU();
  334.     int    cCVsInV    = fnNurb.numCVsInV();
  335.  
  336.     if ((cCVsInU - 1) % 3 != 0 || (cCVsInV - 1) % 3 != 0)
  337.         return false;        // invalid control point count (we only deal with quad patches)
  338.  
  339.     int    cSpansInU    = (cCVsInU - 1) / 3;
  340.     int    cSpansInV    = (cCVsInV - 1) / 3;
  341.  
  342.     if (cSpansInU <= 0 || cSpansInV <= 0)
  343.         return false;        // invalid span count
  344.  
  345.  
  346.     MPointArray rgCVs;
  347.  
  348.     fnNurb.getCVs(rgCVs);
  349.  
  350.     if ((int)rgCVs.length() != cCVsInU * cCVsInV)
  351.         return false;        // inconsistency in cv count
  352.  
  353.     return true;            // all tests passed
  354. }
  355.  
  356.  
  357.  
  358.  
  359. int MyDtShapeGetVertices
  360.     (
  361.         int            iShape, 
  362.         int*        pcVertices, 
  363.         DtVec3f**    prgVertices
  364.     )
  365. {
  366.     *pcVertices        = 0;
  367.     *prgVertices    = NULL;
  368.  
  369.     DtVec3f*    rgVertices;
  370.  
  371.     if (!DtShapeGetVertices(iShape, pcVertices, &rgVertices))
  372.     {
  373.         *pcVertices    = 0;
  374.  
  375.         return 0;
  376.     }
  377.  
  378.     if (!(*prgVertices    = new DtVec3f[*pcVertices]))
  379.     {
  380.         *pcVertices    = 0;
  381.  
  382.         return 0;
  383.     }
  384.  
  385.     memcpy(*prgVertices, rgVertices, *pcVertices * sizeof(DtVec3f));
  386.  
  387.     return 1;
  388. }
  389.  
  390.  
  391. int MyDtShapeGetNormals
  392.     (
  393.         int            iShape, 
  394.         int*        pcNormals, 
  395.         DtVec3f**    prgNormals
  396.     )
  397. {
  398.     *pcNormals    = 0;
  399.     *prgNormals    = NULL;
  400.  
  401.     DtVec3f*    rgNormals;
  402.  
  403.     if (!DtShapeGetNormals(iShape, pcNormals, &rgNormals))
  404.     {
  405.         *pcNormals    = 0;
  406.  
  407.         return 0;
  408.     }
  409.  
  410.     if (!(*prgNormals    = new DtVec3f[*pcNormals]))
  411.     {
  412.         *pcNormals    = 0;
  413.  
  414.         return 0;
  415.     }
  416.  
  417.     memcpy(*prgNormals, rgNormals, *pcNormals * sizeof(DtVec3f));
  418.  
  419.     return 1;
  420. }
  421.  
  422.  
  423.  
  424.  
  425. int    MyDtShapeGetNormals
  426.     (
  427.         MObject&    objInput, 
  428.         MObject&    objOutput, 
  429.         int*        pcNormals, 
  430.         DtVec3f**    prgNormals
  431.     ) 
  432. {
  433.     *pcNormals    = 0;
  434.     *prgNormals    = NULL;
  435.  
  436.     assert(objInput.hasFn(MFn::kMesh) && objOutput.hasFn(MFn::kMesh));
  437.  
  438.     MFnMesh    fnInput(objInput);
  439.     MFnMesh    fnOutput(objOutput);
  440.  
  441.     assert(fnInput.numNormals() == fnOutput.numNormals());
  442.     
  443.     *pcNormals    = fnInput.numNormals();
  444.     *prgNormals    = new DtVec3f[*pcNormals];
  445.  
  446.     if (!*prgNormals)
  447.     {
  448.         *pcNormals    = 0;
  449.  
  450.         return 0;
  451.     }
  452.  
  453.     MFloatVectorArray    rgOrigNormals;
  454.  
  455.     fnInput.getNormals(rgOrigNormals);
  456.  
  457.     assert(*pcNormals == (int)rgOrigNormals.length());
  458.  
  459.     for (int iNormal = 0; iNormal < *pcNormals; iNormal++) 
  460.     {
  461.         (*prgNormals)[iNormal].vec[0]    = rgOrigNormals[iNormal][0];
  462.         (*prgNormals)[iNormal].vec[1]    = rgOrigNormals[iNormal][1];
  463.         (*prgNormals)[iNormal].vec[2]    = rgOrigNormals[iNormal][2];
  464.     }
  465.  
  466.     return 1;
  467. }
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475. int MyDtShapeGetTextureVertices
  476.     (
  477.         int            iShape, 
  478.         int*        pcTexCoords, 
  479.         DtVec2f**    prgTexCoords
  480.     )
  481. {
  482.     *pcTexCoords    = 0;
  483.     *prgTexCoords    = NULL;
  484.  
  485.     DtVec2f*    rgTexCoords;
  486.  
  487.     if (!DtShapeGetTextureVertices(iShape, pcTexCoords, &rgTexCoords))
  488.     {
  489.         *pcTexCoords    = 0;
  490.  
  491.         return 0;
  492.     }
  493.  
  494.     if (!(*prgTexCoords    = new DtVec2f[*pcTexCoords]))
  495.     {
  496.         *pcTexCoords    = 0;
  497.  
  498.         return 0;
  499.     }
  500.     
  501.     memcpy(*prgTexCoords, rgTexCoords, *pcTexCoords * sizeof(DtVec2f));
  502.  
  503.     return 1;
  504. }
  505.  
  506.  
  507.  
  508.  
  509.  
  510. int MyDtShapeGetVerticesColor
  511.     (
  512.         int            iShape, 
  513.         int*        pcColors, 
  514.         DtRGBA**    prgColors
  515.     )
  516. {
  517.     *pcColors    = 0;
  518.     *prgColors    = NULL;
  519.  
  520.     DtRGBA*    rgColors;
  521.  
  522.     if (!DtShapeGetVerticesColor(iShape, pcColors, &rgColors))
  523.     {
  524.         *pcColors    = 0;
  525.  
  526.         return 0;
  527.     }
  528.  
  529.     if (!(*prgColors    = new DtRGBA[*pcColors]))
  530.     {
  531.         *pcColors    = 0;
  532.  
  533.         return 0;
  534.     }
  535.     
  536.     memcpy(*prgColors, rgColors, *pcColors * sizeof(DtRGBA));
  537.  
  538.     return 1;
  539. }
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549. int    MyDtShapeGetControlPoints
  550.     (
  551.         MObject&    objInput, 
  552.         MObject&    objOutput, 
  553.         int*        pcVertices, 
  554.         DtVec3f**    prgVertices
  555.     ) 
  556. {
  557.     *pcVertices        = 0;
  558.     *prgVertices    = NULL;
  559.  
  560.     
  561.     assert(objInput.hasFn(MFn::kNurbsSurface) && objOutput.hasFn(MFn::kNurbsSurface));
  562.  
  563.  
  564.     MFnNurbsSurface    fnOutput(objOutput);
  565.     MFnNurbsSurface    fnInput(objInput);
  566.  
  567.  
  568.  
  569.     MPointArray rgCVs;
  570.  
  571.     fnInput.getCVs(rgCVs);
  572.  
  573.     *pcVertices        = rgCVs.length();
  574.     *prgVertices    = new DtVec3f[*pcVertices];
  575.  
  576.     if (!*prgVertices) 
  577.     {
  578.         *pcVertices    = 0;
  579.  
  580.         return 0;
  581.     }
  582.  
  583.     // WARNING:  Is this homogeneous coordinates? Should I divide w?
  584.     for (int iVertex = 0; iVertex < *pcVertices; iVertex++) 
  585.     {
  586.         (*prgVertices)[iVertex].vec[0]    = (float)rgCVs[iVertex][0];
  587.         (*prgVertices)[iVertex].vec[1]    = (float)rgCVs[iVertex][1];
  588.         (*prgVertices)[iVertex].vec[2]    = (float)rgCVs[iVertex][2];
  589.     }
  590.  
  591.  
  592.     // check for tweaks
  593.     MPlug    plgTweakLoc    = fnOutput.findPlug("tweakLocation");
  594.  
  595.     MObject    objTweakLocVal;
  596.  
  597.     plgTweakLoc.getValue(objTweakLocVal);
  598.  
  599.     if (!objTweakLocVal.isNull())    // tweak found
  600.     {    
  601.         MPlugArray    rgplgTweakLocConnections;
  602.  
  603.         plgTweakLoc.connectedTo(rgplgTweakLocConnections, true, false);        // get source plugs
  604.  
  605.         assert(rgplgTweakLocConnections.length() == 1);
  606.  
  607.         MObject    objTweak = rgplgTweakLocConnections[0].node();
  608.  
  609.         assert(objTweak.hasFn(MFn::kTweak));
  610.  
  611.         MFnGeometryFilter    fnTweak(objTweak);
  612.  
  613.         bool    bRelativeTweak;
  614.  
  615.         fnTweak.findPlug("relativeTweak").getValue(bRelativeTweak);
  616.  
  617.         if (!bRelativeTweak) 
  618.             cout << "\t\tWARNING: Encountered an absolute tweak; treating as relative!" << endl;
  619.  
  620.         MPlug plgOffsets = fnTweak.findPlug("plist")[0].child(0);
  621.  
  622.  
  623.         //    WARNING: Seems like Maya doesn't initialize it's numElements properly!!
  624. //        assert((int)plgOffsets.numElements() == cVertices);
  625.         if ((int)plgOffsets.numElements() != *pcVertices)
  626.             cout << "\t\tWARNING: tweak count doesn't match vertex count!" << endl;
  627.  
  628.         float    fEnvelope    = fnTweak.envelope();
  629.  
  630.         for (int iVertex = 0; iVertex < *pcVertices; iVertex++) 
  631.         {
  632.             DtVec3f    vecOffset;
  633.  
  634.             plgOffsets.elementByLogicalIndex(iVertex).child(0).getValue(vecOffset.vec[0]);
  635.             plgOffsets.elementByLogicalIndex(iVertex).child(1).getValue(vecOffset.vec[1]);
  636.             plgOffsets.elementByLogicalIndex(iVertex).child(2).getValue(vecOffset.vec[2]);
  637.  
  638.             (*prgVertices)[iVertex].vec[0]    += fEnvelope * vecOffset.vec[0];
  639.             (*prgVertices)[iVertex].vec[1]    += fEnvelope * vecOffset.vec[1];
  640.             (*prgVertices)[iVertex].vec[2]    += fEnvelope * vecOffset.vec[2];
  641.         }
  642.     }
  643.             
  644.             
  645.  
  646.     return 1;
  647. }
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665. Mesh::Mesh() 
  666. {
  667.     m_kType                    = Mesh::UNKNOWN;
  668.  
  669.     m_cGroups                = 0;
  670.     m_rgGroups                = NULL;
  671.  
  672.     m_cVertices                = 0;
  673.     m_rgVertices            = NULL;
  674.  
  675.     m_cVertexColors            = 0;
  676.     m_rgVertexColors        = NULL;
  677.  
  678.     m_cNormals                = 0;
  679.     m_rgNormals                = NULL;
  680.  
  681.     m_cTexCoords            = 0;
  682.     m_rgTexCoords            = NULL;
  683.  
  684.     m_cReps                    = 0;
  685.     m_rgReps                = NULL;
  686.  
  687.     m_cFaces                = 0;
  688.     m_rgFaces                = NULL;
  689.  
  690.     m_cFaceIndices            = 0;
  691.  
  692.     m_cBones                = 0;
  693.     m_rgBones                = NULL;
  694.  
  695.     m_cMaxBonesPerFace        = 0;
  696.     m_cMaxBonesPerVertex    = 0;
  697. }
  698.  
  699.  
  700.  
  701. Mesh::~Mesh() 
  702. {
  703.     delete[] m_rgReps;
  704.  
  705.     delete[] m_rgVertices;
  706.     delete[] m_rgNormals;
  707.     delete[] m_rgTexCoords;
  708.     delete[] m_rgVertexColors;
  709.  
  710.     for (int iFace = 0; iFace < m_cFaces; iFace++)
  711.     {
  712.         delete[] m_rgFaces[iFace].m_rgIndices;
  713.     }
  714.  
  715.     delete[] m_rgFaces;
  716.  
  717.     delete[] m_rgGroups;
  718.  
  719.     for (int iBone = 0; iBone < m_cBones; iBone++) 
  720.     {
  721.         delete[] m_rgBones[iBone].m_rgfWeights;
  722.         delete[] m_rgBones[iBone].m_rgiVertices;
  723.     }
  724.  
  725.     delete[] m_rgBones;
  726. }
  727.  
  728.  
  729. Face::Face()
  730. {
  731.     m_cIndices    = 0;
  732.     m_rgIndices    = NULL;
  733.  
  734.     m_iGroup    = -1;
  735. }
  736.  
  737. Face::~Face() 
  738. {
  739. }
  740.  
  741.  
  742. Bone::Bone()
  743. {
  744.     m_szName        = NULL;
  745.  
  746.     m_cWeights        = 0;
  747.     m_rgfWeights    = NULL;
  748.     m_rgiVertices    = NULL;
  749.  
  750.     m_cReps            = 0;
  751. }
  752.  
  753. Bone::~Bone()
  754. {
  755. }